﻿// Genererate a Health Check Failure if a File or group of files that match a particular specification exceed an enumerated maximum size.
// Wild Cards *.* , ?, #
// SQL Error Files

namespace Wolfpack.Contrib.Checks.FileCheck
{
    using System;
    using System.IO;
    using Wolfpack.Core;
    using Wolfpack.Core.Interfaces;
    using Wolfpack.Core.Interfaces.Entities;

    public class FileThresholdConfig : PluginConfigBase
    {
        public string DirectoryPath { get; set; }

        // Size in bytes.
        public string MaxSize { get; set; }

        public string IncludeSubDirectories { get; set; }

        public string SearchPattern { get; set; }
    }

    public class FileThreshold : IHealthCheckPlugin
    {
        protected readonly FileThresholdConfig config;
        protected readonly PluginDescriptor identity;

        /// <summary>
        /// default ctor
        /// </summary>
        public FileThreshold(FileThresholdConfig fileThresholdConfig)
        {
            config = fileThresholdConfig;

            identity = new PluginDescriptor
            {
                Description = string.Format("Reports if files in, '{0},' matching the search pattern of, '{1},' are cumlatively larger than, '{2},' bytes.",
                config.DirectoryPath,
                config.SearchPattern,
                config.MaxSize),
                TypeId = new Guid("9A781129-66AD-4fb3-8F0D-0702731160EA"),
                Name = config.FriendlyId
            };
        }

        public Status Status { get; set; }

        public PluginDescriptor Identity
        {
            get { return identity; }
        }

        public void Initialise()
        {
            // do nothing
        }

        public void Execute()
        {
            FileInfo[] fi;

            long totalSize = 0;

            try
            {
                DirectoryInfo di = new DirectoryInfo(config.DirectoryPath);

                if (di.Exists)
                { 

                    if ("1" == config.IncludeSubDirectories)
                    {
                        fi = di.GetFiles(config.SearchPattern, SearchOption.AllDirectories);
                    }
                    else
                    {
                        fi = di.GetFiles(config.SearchPattern, SearchOption.TopDirectoryOnly);
                    }

                    foreach (FileInfo f in fi)
                    {
                        // in bytes
                        totalSize += f.Length;
                    }
                    HealthCheckData result = new HealthCheckData
                    {
                        Identity = this.Identity,
                        Info = string.Format("Reports if files in, '{0},' matching the search pattern of, '{1},' are cumlatively larger than, '{2},' bytes.",
                        config.DirectoryPath,
                        config.SearchPattern,
                        config.MaxSize),
                        Result = (totalSize < Int64.Parse(config.MaxSize)),
                    };

                    if (result.Result.GetValueOrDefault(false))
                    {
                        result.ResultCount = totalSize;
                        result.Properties = new ResultProperties
                                                {
                                                    {"Directory", config.DirectoryPath},
                                                    {"MaxSize", config.MaxSize},
                                                    {"Search Pattern", config.SearchPattern},
                                                    {"Actual Size", totalSize.ToString()}
                                                };
                    }

                    Messenger.Publish(result);
                }
            }
            catch (Exception e)
            {
                Logger.Debug("Unable to iterate files, {0}.", e.InnerException.Message);
            }

            Logger.Debug("Done checking file thresholds. Directory: '{0}' Search Pattern '{1}' Max Size in bytes: '{2}' Actual Size in bytes: '{3}'.",
                config.DirectoryPath,
                config.SearchPattern,
                config.MaxSize,
                totalSize.ToString());
        }
    }
}